<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文档对象模型-节点之间的关系和属性说明(Document Object Model - Description of Relationships and Attributes between Nodes)</title>
  <!-- 
  在JavaScript的文档对象模型（DOM）中，节点之间的关系和属性是理解和操作文档结构的关键。

  在 DOM 的上下文中，节点是节点树中的单个点。文档本身、元素、文本以及注释都是节点。

  1. 节点类型
  DOM中的节点主要有以下几种类型：
  - 元素节点（Element Node）：表示HTML或XML文档中的元素（如 `<div>` 、 `<p>` 等）。
  - 文本节点（Text Node）：表示元素或属性中的文本内容。
  - 属性节点（Attribute Node）：表示元素的属性（如 `class` 、 `id` 等）。
  - 文档节点（Document Node）：表示整个文档。
  - 注释节点（Comment Node）：表示文档中的注释。

  2. 节点关系
  节点之间的关系主要体现在以下几个方面：
  - 父子关系：
    - 每个节点都有一个父节点（除了根节点），可以通过 `parentNode` 属性访问。
    - 节点可以有多个子节点，通过 `childNodes` 属性访问所有子节点，或使用 `firstChild` 和 `lastChild` 访问第一个和最后一个子节点。

  - 兄弟关系：
    - 同一父节点下的节点称为兄弟节点。可以通过 `nextSibling` 和 `previousSibling` 属性访问相邻的兄弟节点。
    - 使用 `children` 属性可以获取所有子元素节点（不包括文本节点和注释节点）。

  3. 节点属性
  节点对象有许多重要的属性，可以用来获取或设置节点的相关信息：
  -  `nodeName` ：返回节点的名称，元素节点返回标签名（如 `"DIV"` ），文本节点返回 `"#text"` 。
  -  `nodeType` ：返回节点的类型，元素节点为 `1` ，文本节点为 `3` ，属性节点为 `2` ，文档节点为 `9` 。
  -  `childNodes` ：返回一个包含所有子节点的NodeList集合。
  -  `firstChild` ：返回第一个子节点。
  -  `lastChild` ：返回最后一个子节点。
  -  `nextSibling` ：返回下一个兄弟节点。
  -  `previousSibling` ：返回上一个兄弟节点。

  4. 节点操作
  通过JavaScript，开发者可以动态地操作节点：
  - 添加节点：使用 `appendChild()` 、 `insertBefore()` 等方法将新节点添加到现有节点中。
  - 删除节点：使用 `removeChild()` 方法从父节点中删除指定的子节点。
  - 替换节点：使用 `replaceChild()` 方法替换现有节点。

  5. 事件处理
  节点可以响应用户的交互事件，如点击、悬停等。可以通过 `addEventListener()` 方法为节点添加事件监听器。
   -->
</head>

<body>

  <h3>1. 元素节点</h3>
  <div id="myDiv">Hello, World!</div>

  <h3>2. 文本节点</h3>
  <p>This is a <span>paragraph</span> with some <strong>text</strong>.</p>

  <h3>3. 注释节点</h3>
  <!-- This is a comment -->

  <h3>4. 文档节点</h3>
  <p>This is a paragraph.</p>

  <h3>5. 属性节点</h3>
  <img src="../../../01_html-css/images/diqiu.jpg" alt="An image" width="100" height="100">

  <h3>6. 节点关系</h3>
  <ul class="node-list">
    <li>Node 1</li>
    <li>Node 2</li>
    <li>Node 3</li>
  </ul>

  <script>
    // 1. 元素节点
    var myDiv = document.getElementById("myDiv");
    console.log("元素节点", myDiv.nodeType); // 1
    console.log("元素节点", myDiv.nodeName); // "DIV"

    // 2. 文本节点
    var textNode = document.createTextNode("Hello, World!");
    console.log("文本节点", textNode.nodeType); // 3
    console.log("文本节点", textNode.nodeName); // "#text"

    // 3. 注释节点
    var commentNode = document.createComment("This is a comment");
    console.log("注释节点", commentNode.nodeType); // 8
    console.log("注释节点", commentNode.nodeName); // "#comment"

    // 4. 文档节点
    var documentNode = document;
    console.log("文档节点", documentNode.nodeType); // 9

    // 5. 属性节点
    var img = document.querySelector("img");
    var srcAttr = img.getAttributeNode("src");
    console.log("属性节点", srcAttr.nodeType); // 2
    console.log("属性节点", srcAttr.nodeName); // "src"

    // 6. 节点关系
    var nodeList = document.querySelector(".node-list");
    var firstChild = nodeList.firstChild;
    console.log("节点关系- 所有子节点", nodeList.childNodes);
    console.log("节点关系- 第一个子节点", firstChild);
    console.log("节点关系- 下一个兄弟节点", firstChild.nextSibling);
    console.log("节点关系- 下一个兄弟节点", firstChild.nextSibling.nextSibling);
    console.log("节点关系- 父节点", firstChild.parentNode);
    console.log("节点关系- 最后一个子节点", nodeList.lastChild);
    console.log("节点关系- 上一个兄弟节点", nodeList.lastChild.previousSibling);

  </script>

</body>

</html>